/**
 * Created by liaoxd on 2017/12/17.
 */
define([
  './libs/calendar/jquery/jquery-1.7.1.min.js',
  './libs/calendar/jquery/jquery.validate.min.js',
  './libs/calendar/jquery/jquery.validate.expand.min.js',
  './libs/calendar/jquery/jquery.validate.messages_cn.min.js',
  './libs/calendar/jquery/jquery.validate.messages_cn.min.js',
  './libs/calendar/jquery/jquery.validate.expand.messages_cn.min.js',
  './libs/calendar/jquery/jquery.hoverIntent.min.js',
  './libs/calendar/jquery/jquery.metadata.min.js',
  './libs/calendar/jquery/jquery.form.min.js',
  './libs/calendar/jquery/jquery.easing.min.js',
  './libs/calendar/jquery/chili-1.7.pack.js',
  './libs/calendar/jquery/jquery.dimensions.min.js',
  './libs/calendar/jquery/jquery.accordion.min.js',
  './libs/calendar/jquery/jquery.json-2.3.min.js',
  './libs/calendar/mbMenu/mbMenu.min.js',
  './libs/calendar/ligerUI/ligerui.all.js',
  './libs/calendar/bione/BIONE.js',
  './libs/calendar/bione/Common.js',
  './libs/calendar/bione/json2.js',
  './libs/calendar/backbone/underscore.js',
  './libs/calendar/calendar/moment-2.2.1.js',
  './libs/calendar/calendar/clndr.js',
  './libs/calendar/calendar/moment-2.2.1.js',
  './libs/calendar/classics/ligerui-custom.css',
  './libs/calendar/classics/template/common.css',
], function (require, exports) {
  // page加载完成后调用ready方法
  exports.ready = function (hashCode, data, cite) {
    var App = {
      parentApp : parent.App,
      appCode : "undefined",
      calendarCode : "undefined",
      calendarDayTypeCache : {},//日历天类型缓存Map<appCode,dayTypes>
      calendarDetailCache : {},//日历配置详细缓存Map<appCode-calendarCode,oldData>
      dayTypes : {},//当前操作的日历天类型<typeCode,{typeColor,typeName}>
      data : {},//当前操作的详情存储
      UN_INIT_COLOR : "#F4F4F4",
      DEFAULT_DAY : {
        WORK_DAY : "1",
        NON_WORK_DAY : "0"
      },
      changed : false,
      months : null,
      init : function() {
        this.initCss();
        this.renderCalendar();
        this.initEvent();
        this.changeCalendar();
        //初始化完成后将此对象交个父对象
        this.parentApp.configApp = this;
        App.$legend = $("#legend");
      },
      /**
       *初始布局
       **/
      initCss : function() {
        var $tab = $("#container");
        this.$tab = $tab;
        //toolbar
        var divTool = $("#toolBar");
        divTool.attr({
          id : "toolbar"
        }).css({
          width : "100%"
        });
        $tab.append(divTool);
        divTool.ligerToolBar({
          items : [ {
            text : '保存',
            click : function() {
              App.save();
            },
            icon : 'save'
          }, {
            line : true
          }, {
            text : '重置',
            click : function() {
              App.reset();
            },
            icon : 'refresh'
          } ]
        });
        var html = [], combs = [ "initType", "chooseYear" ], combNames = [
            "初始化方式", "选择年份" ], l = combs.length;
        var btnHTML = [];
        btnHTML.push('<div id="initBtn" class="l-dialog-btn" style="margin-top:1px;">');
        btnHTML.push('<div class="l-dialog-btn-l"></div>');
        btnHTML.push('<div class="l-dialog-btn-r"></div>');
        btnHTML.push('<div class="l-dialog-btn-inner">初始化</div>');
        divTool.append(btnHTML.join(""));
        $("#initBtn").click(function() {
          if (!App._$initType) {
            App._$initType = $.ligerui.get("initType");
          }
          App.initDateType(App._$initType.getValue());
        });
        for ( var i = 0; i < l; i++) {
          html.push("<div style='width:220px;float:right;margin-top:3px;' class='custom-editor l-toolbar-item l-panel-btn l-toolbar-item-hasicon'><input id='");
          html.push(combs[i]);
          html.push("' /><div>");
          html.push(combNames[i]);
          html.push("：</div></div>");
        }
        divTool.append(html.join(""));
        //生成2000-2050年供选
        var years = [];
        for ( var i = 2000; i <= 2050; i++) {
          years.push({
            text : i + "年",
            id : i
          });
        }
        $("#chooseYear").ligerComboBox({
          initValue : (new Date().getFullYear()),
          data : years,
          onSelected : function(year, text) {
            App.chooseYear(year);
          }
        });
        $("#initType").ligerComboBox({
          initValue : "0",
          data : [ {
            text : "周六、日休息",
            id : "0"
          }, {
            text : "仅周日休息",
            id : "1"
          }, {
            text : "全为工作日",
            id : "2"
          } ]
        });
        $(".custom-editor").css("float", "right");
        $(".custom-editor>div").css("float", "right");
        //calendars
        this.$calendars = $("#calendars");
        this.$calendars.height($(document).height() - 28 - 20);//28toolbar,20legend
        //shim
        this.$shim = $(".l-window-mask");
      },
      /**
       *渲染日历
       **/
      renderCalendar : function() {
        var self = this;
        this.months = [];
        for ( var i = 1; i <= 12; i++) {
          var clndr = $("<div class='calendar' id='month_"+i+"'></div>"), clndrObj = null;
          clndrObj = clndr.clndr({
            month : "September",
            year : 2012,
            template : $("#template-calendar").html(),
            startWithMonth : (new Date().getFullYear()) + "-"
                + (i < 10 ? ("0" + i) : i) + "-01",
            daysOfTheWeek : [ '日', '一', '二', '三', '四', '五', '六' ],
            showAdjacentMonths : false
          });
          this.$calendars.append(clndr);
          this.months.push(clndrObj);
        }
      },
      /**
       *选择年份
       **/
      chooseYear : function(year) {
        if (this.months != null) {
          for ( var i = 1; i <= 12; i++) {
            this.months[i - 1].month = moment(
                year + "-" + (i < 10 ? ("0" + i) : i) + "-01")
                .startOf('month');
            this.months[i - 1].render();
          }
          this.loadDateType();
        }
      },
      initEvent : function() {
        //selecter
        var $body = $("body"), bodyWidth = $body.width(), bodyHeight = $(
            window).height(), colorSelecter = $("<div id='type-select'></div");
        this.$colorSelecter = colorSelecter;
        $body.append(colorSelecter);
        colorSelecter.hover(function() {
          App.showColorSelecter();
        }, function() {
          App.hideColorSelecter();
        });
        this.loadColorSelecterItem();
        //左键
        this.$calendars.click(function(e) {
          var thisClickTime = new Date().getTime();
          if (App._lastClickTime
              && ((thisClickTime - App._lastClickTime) < 200)) {
            return;//双击;
          }
          App._lastClickTime = thisClickTime;
          App._changeSingleDayType(e);
        });
        //右键
        $body
            .contextmenu(function(e) {
              var tgt = e.target;
              if (tgt.className.indexOf("calendar-day") < 0) {
                colorSelecter.hide();
                return;
              }
              if (tgt.className == ("calendar-day-link")) {
                //固定活动对象样式
                tgt.style.fontWeight = "bolder";
                tgt.style.margin = "0px";
                tgt.style.lineHeight = "16px";
                tgt.style.border = "1px solid #000";
                //操作对象设为父div
                tgt = tgt.parentNode;
              }
              App._unBindLastDayEvent();
              App._currentClickDay = $(tgt);
              App._currentClickDay.bind("mouseenter", function() {
                App.showColorSelecter();
              }).bind("mouseleave", function() {
                App.hideColorSelecter();
              });
              var csWidth = colorSelecter.width(), csHeight = colorSelecter
                  .height(), offset = App._currentClickDay
                  .offset(), top, left;
              if ((bodyWidth - offset.left - tgt.offsetWidth) > csWidth) {
                left = offset.left + tgt.offsetWidth + "px";
              } else {
                left = offset.left - csWidth - 1 + "px";
              }
              if ((bodyHeight - offset.top) > csHeight) {
                top = offset.top + "px";
              } else {
                top = offset.top - csHeight + tgt.offsetHeight
                    + "px";
              }
              colorSelecter.css({
                top : top,
                left : left
              });
              App.showColorSelecter();
            });
        //选择
        colorSelecter.click(function(e) {
              var liObj = App._getActiveColorLi(e.target), code;
              if (liObj) {
                //选择
                code = liObj.li.className.substring(
                    liObj.startIndex + 10,
                    liObj.startIndex + 11);
                App._currentClickDay
                    && App.changeDayType(
                        App._currentClickDay[0], code);
                App._hideColorSelecter();
                App._currentClickDay = null;
              }
            });
      },
      _changeSingleDayType : function(e) {
        var tgt = e.target;
        if (tgt.className.indexOf("calendar-day") < 0) {
          return;
        }
        if (tgt.className == ("calendar-day-link")) {
          //操作对象设为父div
          tgt = tgt.parentNode;
        }
        //非工作->工作,工作->休息
        App.changeDayType(
                tgt,
                App.DEFAULT_DAY[App.data[tgt.id] == App.DEFAULT_DAY.WORK_DAY ? "NON_WORK_DAY" : "WORK_DAY"]);
      },
      _getActiveColorLi : function(target) {
        var li = target, startIndex = -1;
        startIndex = li.className.indexOf("type-code");
        if (startIndex < 0) {
          li = $(li).parents(".type-select-li");
          if (li.length) {
            li = li[0];
            startIndex = li.className.indexOf("type-code");
          }
        }
        if (startIndex >= 0) {
          return {
            li : li,
            startIndex : startIndex
          };
        }
        return null;
      },
      /**
       *加载选项
       **/
      loadColorSelecterItem : function() {
        var box = this.$colorSelecter, data = this.dayTypes, html = [];
        html.push("<ul>");
        $.each(
                data,
                function(code, item) {
                  html.push("<li class='type-select-li type-code-");
                  html.push(code);
                  html.push("'><table><tr>");
                  html.push("<td><div class='type-select-color' style='background-color:");
                  html.push(item.color);
                  html.push(";'></div></td>");
                  html.push("<td><div class='type-select-text'>");
                  html.push(item.name);
                  html.push("</div></td>");
                  html.push("</tr></table></li>");
                  html.push("</li>");
                });
        html.push("</ul>");
        box.html(html.join(""));
      },
      /**
       *显示自定义类型选择框
       **/
      showColorSelecter : function() {
        if (this._timerForColor) {
          clearTimeout(this._timerForColor);
        }
        App.$colorSelecter.show();
      },
      /**
       *延迟隐藏自定义选择框
       **/
      hideColorSelecter : function() {
        if (this._timerForColor) {
          clearTimeout(this._timerForColor);
        }
        this._timerForColor = setTimeout(this._hideColorSelecter, 300);
      },
      /**
       *立即隐藏自定义选择框
       **/
      _hideColorSelecter : function() {
        App.$colorSelecter.hide();
        App._unBindLastDayEvent();
      },
      /**
       *移除上一个日期的事件
       **/
      _unBindLastDayEvent : function() {
        if (App._currentClickDay) {
          App._currentClickDay.children("a").attr("style", "");//移除活动对象样式
          App._currentClickDay.unbind("mouseleave").unbind("mouseenter");
        }
      },
      /**
       *初始化工作日
       **/
      initDateType : function(initType) {
        var self = this;
        //全置为工作
        $.each($(".day"), function(i, d) {
          self.changeDayType(d, App.DEFAULT_DAY.WORK_DAY);
        });
        if (initType == "0" || initType == "1") {
          $.each($(".week-0"), function(i, d) {
            self.changeDayType(d, App.DEFAULT_DAY.NON_WORK_DAY);
          });
          if (initType == "0") {
            $.each($(".week-6"), function(i, d) {
              self.changeDayType(d, App.DEFAULT_DAY.NON_WORK_DAY);
            });
          }
        }
      },
      /**
       *设置某天的类型
       **/
      changeDayType : function(elem, dayType) {
        App.changed = true;
        elem.style.backgroundColor = App.dayTypes[dayType].color;
        var id = this.getCalendarDayID(elem);
        App.data[id] = dayType;
      },
      /**
       *获取天id
       **/
      getCalendarDayID : function(elem) {
        return elem.className.split(" ")[1];
      },
      /**
       *渲染日历天类型(批量重绘)
       **/
      loadDateType : function() {
        App.hideCalendar();
        var data = App.data, tp;
        for ( var date in data) {
          if (data.hasOwnProperty(date)) {
            tp = App.dayTypes[App.data[date]];
            $("#" + date).css("background-color",
                tp ? tp.color : App.UN_INIT_COLOR);
          }
        }
        App.showCalendar();//显示
      },
      /**
       *更换日历
       **/
      changeCalendar : function(appCode, calendarCode) {
        if (appCode && calendarCode) {
          this.appCode = appCode;
          this.calendarCode = calendarCode;
        }
        //清除所有变色
        $(".day").css("background-color", this.UN_INIT_COLOR);
        this.fetchCalendarTypes();
        App.changed = false;
      },
      showCalendar : function() {
        this.$calendars.css("visibility", "");
        this.$shim.hide();
      },
      hideCalendar : function() {
        this.$calendars.css("visibility", "hidden");
        this.$shim.show();
      },
      /**
       *获取日历天类型
       **/
      fetchCalendarTypes : function(appCode) {
        var appCode = App.appCode, cache = App.calendarDayTypeCache;
        if (!App.parentApp.typeChanged[App.appCode] && cache[appCode]) {
          //已缓存且类型并未变化
          this.formatRenderDayTypes(cache[appCode]);
          App.loadColorSelecterItem();//加载右键选择内容
          App.fetchCalendarData();
        } else {
          //远程获取
          yufp.service.request({
            url : backend.useCalendarService + "/fetchCalendarTypes.json?d=" + (new Date()),
            type : "post",
            data : {
              appCode : appCode
            },
            callback : function(code, message, result) {
              cache[appCode] = result || {};
              App.formatRenderDayTypes(cache[appCode]);
              App.loadColorSelecterItem();//加载右键选择内容
              App.fetchCalendarData();
            }
          });
        }
      },
      /**
       *格式化天类型
       **/
      formatRenderDayTypes : function(types) {
        var tps = {}, legendHtml = [], color = null;
        for ( var i = 0, l = types.length; i < l; i++) {
          color = types[i].typeColor.length == 6 ? ("#" + types[i].typeColor) : types[i].typeColor;
          tps[types[i].id.typeCode] = {
            color : color,
            name : types[i].typeName
          };
          //渲染图例
          legendHtml.push(this._getLegendItem(types[i].typeName, color));
        }
        App.dayTypes = tps;
        legendHtml.push(this._getUnDefinedLegend());
        App.$legend.html(legendHtml.join(""));
      },
      _getUnDefinedLegend : function() {
        return this._getLegendItem("未初始化", this.UN_INIT_COLOR);
      },
      _getLegendItem : function(text, color) {
        return "<li class='legend-item-color' style='background-color:"+color+"'></li><li class='legend-item-text'>" + text + "</li>";
      },
      /**
       *获取日历配置信息
       **/
      fetchCalendarData : function() {
        var appCode = App.appCode, calendarCode = App.calendarCode, pk = appCode
            + "-" + calendarCode, cache = App.calendarDetailCache;
        if (!App.parentApp.typeChanged[App.appCode] && cache[pk]) {
          App.data = App._getTranscript(cache[pk]);
          App.loadDateType();
        } else {
          //远程获取
          yufp.service.request({
            url : backend.useCalendarService + "/fetchCalendarData.json?d="  + (new Date()),
            type : "post",
            data : {
              appCode : appCode,
              calendarCode : calendarCode
            },
            callback : function(code, message, result) {
              cache[pk] = App._formatCalendarData(result || {});
              App.data = App._getTranscript(cache[pk]);
              delete App.parentApp.typeChanged[App.appCode];//清除变更标识
              App.loadDateType();
            }
          });
        }
      },
      _formatCalendarData : function(data) {
        var formatData = {}, id;
        for ( var d in data) {
          id = "calendar-day-" + d.substring(0, 4) + "-" + d.substring(4, 6) + "-" + d.substring(6, 8);
          formatData[id] = data[d];
        }
        return formatData;
      },
      /**
       *重置
       **/
      reset : function() {
        this.changeCalendar();
      },
      /**
       *保存
       **/
      save : function() {
        var appCode = App.appCode, calendarCode = App.calendarCode, saveData = this._ratioIncremental(), adds = null, upds = null, dels = null;
        if (!saveData.isChange) {
          return;
        }
        //add
        if (saveData.addData != null) {
          adds = [];
          for ( var d in saveData.addData) {
            if (saveData.addData.hasOwnProperty(d)) {
              adds.push({
                id : {
                  appCode : appCode,
                  calendarCode : calendarCode,
                  dateValue : d.substring(13, 23).split("-").join("")
                },
                typeCode : App.data[d]
              });
            }
          }
        }
        //upd
        if (saveData.updData != null) {
          upds = {};
          for ( var d in saveData.updData) {
            if (saveData.updData.hasOwnProperty(d)) {
              if (!upds[App.data[d]]) {
                upds[App.data[d]] = [];
              }
              upds[App.data[d]].push(d.substring(13, 23).split("-").join(""));
            }
          }
          for ( var i in upds) {
            upds[i] = upds[i].join(",");
          }
        }
        //del
        dels = saveData.delData.join(",");
        yufp.service.request({
          url : backend.useCalendarService + "/save?d=" + (new Date()),
          type : "post",
          data : {
            appCode : appCode,
            calendarCode : calendarCode,
            adds : adds ? JSON2.stringify(adds) : "",
            upds : upds ? JSON2.stringify(upds) : "",
            dels : dels
          },
          callback : function(code, message, res) {
            if (res === true) {
              //更新缓存
              App.calendarDetailCache[appCode + "-" + calendarCode] = App._getTranscript(App.data);
              App.changed = false;
              BIONE.tip("保存成功！");
            }
          }
        });
      },
      /**
       *增量比对
       **/
      _ratioIncremental : function() {
        var appCode = App.appCode, calendarCode = App.calendarCode, newData = App.data, oldData = App.calendarDetailCache[appCode
            + "-" + calendarCode], addData = null, updData = null, delData = [];
        for ( var d in newData) {
          if (!oldData[d]) {
            addData || (addData = {});
            //新增
            addData[d] = newData[d];
          } else if (oldData[d] !== newData[d]) {
            updData || (updData = {});
            //修改
            updData[d] = newData[d];
          }
        }
        for ( var d in oldData) {
          if (!newData[d]) {
            //删除
            delData.push(d);
          }
        }
        return {
          isChange : (addData || updData || delData.length),
          addData : addData,
          delData : delData,
          updData : updData
        };
      },
      /**
       *获取一个副本
       **/
      _getTranscript : function(src) {
        var copy = {};
        for ( var i in src) {
          copy[i] = src[i];
        }
        return copy;
      }
    };
    yufp.custom.vue({
      el: cite.el,
      data: function () {
        return {
        };
      },
      mounted: function() {
        App.init();
      },
      methods: {}
    });
  };
});